package com.itheima.mall.dubbo.api.ums;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mall.commons.page.PageResult;
import com.itheima.mall.dubbo.mapper.ums.MenuMapper;
import com.itheima.mall.entity.domain.dto.MenuDto;
import com.itheima.mall.entity.domain.ums.Menu;
import com.itheima.mall.entity.domain.ums.RoleMenuRelation;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 后台菜单表 服务实现类
 * </p>
 *
 * @author qinglang
 * @since 2022-07-05
 */
@DubboService
public class MenuImplService extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private RoleMenuRelationService roleMenuRelationService;

    @Override
    public void create(Menu menu) {
        this.save(menu);
    }

    @Override
    @Transactional
    public void delete(Integer id) {
        this.removeById(id);
        roleMenuRelationService.remove(new LambdaQueryWrapper<RoleMenuRelation>().eq(Objects.nonNull(id), RoleMenuRelation::getMenuId, id));
    }

    @Override
    public PageResult list(Integer parentId, Integer pageNum, Integer pageSize) {
        Page<Menu> menuPage = new Page<>(pageNum, pageSize);
        Page<Menu> page = this.page(menuPage,new LambdaQueryWrapper<Menu>().eq(Objects.nonNull(parentId),Menu::getParentId,parentId));
        PageResult init = PageResult.init(page.getRecords(), page.getCurrent(), page.getSize(), page.getTotal());
        return init;
    }

    @Override
    public List<MenuDto> treeList() {
    return getAllMenus();
    }

    @Override
    public void updateM(Menu menu) {
        this.save(menu);
    }

    @Override
    public void updateHidden(Integer id, Integer hidden) {
        this.update(new LambdaUpdateWrapper<Menu>().eq(Objects.nonNull(id),Menu::getId,id).set(Objects.nonNull(hidden),Menu::getHidden,hidden));
    }

    @Override
    public Menu menu(Integer id) {
        Menu menu = this.getById(id);
        return menu;
    }

    /**
     * 获取层级结构菜单数据集合
     * @return
     */
    public List<MenuDto> getAllMenus() {
        //取出所有的内容
        List<Menu> menus = this.list();
        //创建用于前端展示数据的MenuDto实体类集合
        List<MenuDto> menuDtos = new ArrayList<>();
        //遍历所有菜单数据
        for (Menu menu : menus) {
            //找出一级分类 赋值到menuDto类 并加入到集合中去
            if (menu.getParentId() == 0) {
                MenuDto menuDto = new MenuDto();
                BeanUtils.copyProperties(menu, menuDto);
                //为一级分类添加子分类
                menuDto.setChildren(getChildrens(menuDto, menus));
                menuDtos.add(menuDto);
            }
        }
        return menuDtos;
    }

    /**
     * 获取层级子菜单数据集合
     * @param root
     * @param menus
     * @return
     */
    private ArrayList<MenuDto> getChildrens(MenuDto root, List<Menu> menus) {
        //由于子分类下可能还有子分类 此处需要再创建一个MenuDto实体类集合
        ArrayList<MenuDto> menuDtos = new ArrayList<>();
        //再次对所有菜单数据进行遍历
        for (Menu menu : menus) {
            //取出相应子类 加到集合中并返回 （此处利用menu中的id字段和pid字段确立父子关系）
            if (root.getId().equals(menu.getParentId())) {
                MenuDto menuDto = new MenuDto();
                BeanUtils.copyProperties(menu, menuDto);
                //使用递归 逐层级设置各父子分类 直到锁遍历的菜单没有子分类
                menuDto.setChildren(getChildrens(menuDto, menus));
                //最后加入到集合中去
                menuDtos.add(menuDto);
            }
        }
        return menuDtos;
    }
}
